package com.gitee.deament.server.core.cli.db.str;

import cn.hutool.core.util.NumberUtil;
import com.gitee.deament.server.config.SystemConfig;
import com.gitee.deament.server.core.annotation.CliHander;
import com.gitee.deament.server.core.cli.AbstractCli;
import com.gitee.deament.server.core.data.ConnectData;
import com.gitee.deament.server.core.data.datatype.Value;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.Date;
import java.util.List;

/**
 * INCR key
 * 可用版本： >= 1.0.0
 * 时间复杂度： O(1)
 * 为键 key 储存的数字值加上一。
 *
 * 如果键 key 不存在， 那么它的值会先被初始化为 0 ， 然后再执行 INCR 命令。
 *
 * 如果键 key 储存的值不能被解释为数字， 那么 INCR 命令将返回一个错误。
 *
 * 本操作的值限制在 64 位(bit)有符号数字表示之内。
 *
 * Note
 *
 * INCR 命令是一个针对字符串的操作。 因为 Redis 并没有专用的整数类型， 所以键 key 储存的值在执行 INCR 命令时会被解释为十进制 64 位有符号整数。
 * @author
 */
@CliHander(command = "INCR")
public class INCRcli extends AbstractCli {
    @Override
    public void executeCli(ChannelHandlerContext channelHandlerContext, String command) {
        List<String> values = getValues(command);
        if (values.size() != 2) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ERR wrong number of arguments for 'INCR' command"));
            return;
        }
        int db = ConnectData.SELECT_DB_STORAGE.getUseDB(channelHandlerContext.channel().id().asLongText());
        String key=values.get(1);
        Value<String> stringData = SystemConfig.dbData.getStringData(db, key);
        Value<String> newValue= new Value<>();
        newValue.setValue(1+"");
        if(stringData==null){
            SystemConfig.dbData.setStringData(db, key,newValue);
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(SystemConfig.dbData.getStringData(db, key).getValue()));
        } else{
            Date date = stringData.getExpirDateTime();
            if ((date.compareTo(new Date())) <= 0) {
                SystemConfig.dbData.setStringData(db, key,newValue);
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(SystemConfig.dbData.getStringData(db, key).getValue()));
                return;
            }
            if(NumberUtil.isInteger(stringData.getValue())){
                //TODO 线程安全的问题待解决
                newValue.setValue(1+Integer.parseInt(stringData.getValue())+"");
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(SystemConfig.dbData.getStringData(db, key).getValue()));
            }else{
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ERR value is not an integer or out of range"));
                return;

            }
        }


    }
}
